﻿using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using WCS.Controls;
using WCS.Controls.RunLog;
using WCS.Utils;

namespace WCS.Entity
{
    [SugarTable("WCS_Warehouse")]
    public class Warehouse
    {
        /// <summary>
        /// 层数
        /// </summary>
        public string layer { get; set; }

        /// <summary>
        /// 仓库号
        /// </summary>
        public string WarehouseCode { get; set; }

        /// <summary>
        /// 是否满料
        /// </summary>
        public int IsFullMaterial { get; set; }

        /// <summary>
        /// 物料类型
        /// </summary>
        public string MaterialType { get; set; }

        /// <summary>
        /// ID
        /// </summary>
        public string ID { get; set; }

        /// <summary>
        /// 第一个是否有货
        /// </summary>
        public int Goods1 { get; set; }

        /// <summary>
        /// 第二个是否有货
        /// </summary>
        public int Goods2 { get; set; }

        /// <summary>
        /// 下一个物料类型
        /// </summary>
        public string NextMaterialType { get; set; }

        /// <summary>
        /// 是否可入
        /// </summary>
        public int IsIN { get; set; }

        /// <summary>
        /// 是否可出
        /// </summary>
        public int IsOUT { get; set; }

        /// <summary>
        /// 入库时间
        /// </summary>
        [SugarColumn(IsIgnore = true)]
        public int count { get; set; }

        /// <summary>
        /// 数据库连接对象
        /// </summary>
        static SqlSugarDapper _SqlSugarDapper = SqlSugarDapper.GetDbContext();

        /// <summary>
        /// 判断是不是满料
        /// </summary>
        public static Warehouse IsPushMes(string Id)
        {
            var warehouse = _SqlSugarDapper.DB.Queryable<Warehouse>().Where(w => w.ID == Id).First();

            return warehouse;
        }

        /// <summary>
        /// 根据物料类型查找所在仓库
        /// </summary>
        /// <param name="material"></param>
        /// <returns></returns>
        public static List<WarehouseInfo> GetWarehouseByMaterialTypeOut11(int isFullMaterial, string materialType, string warehouseCode)
        {
            try
            {
                List<WarehouseInfo> WarehouseInfoList = new List<WarehouseInfo>();

                var warehouseList = _SqlSugarDapper.DB.SqlQueryable<WarehouseInfo>($@"SELECT * FROM WCS_WarehouseInfo WHERE ID IN (  SELECT   ID  FROM   WCS_Warehouse
                        WHERE   IsFullMaterial = {isFullMaterial}  AND MaterialType = '{materialType}' AND WarehouseCode='{warehouseCode}' AND IsOUT = 1 )
                     ORDER BY CreateTime").ToList();

                var warehouseListChangeType = _SqlSugarDapper.DB.SqlQueryable<Warehouse>($@"SELECT   ID  FROM   WCS_Warehouse
                        WHERE   IsFullMaterial = {isFullMaterial}  AND MaterialType = '{materialType}' AND WarehouseCode='{warehouseCode}' AND IsOUT = 1 and NextMaterialType <> ''").ToList();

                if (warehouseListChangeType.Count != 0)
                {
                    foreach (var warehouses in warehouseListChangeType)
                    {
                        GetWarehouseInfo(isFullMaterial, warehouses.ID, ref WarehouseInfoList);
                        if (WarehouseInfoList.Count == 2)
                        {
                            return WarehouseInfoList;
                        }
                    }
                }

                var warehouseListGroup = warehouseList.GroupBy(g => g.ID).ToList();

                foreach (var warehouses in warehouseListGroup)
                {
                    GetWarehouseInfo(isFullMaterial, warehouses.Key, ref WarehouseInfoList);
                    if (WarehouseInfoList.Count == 2)
                    {
                        return WarehouseInfoList;
                    }
                }
                return null;
            }
            catch (Exception ex)
            {
                RunLog.runLog.Error($@"【 GetWarehouseByMaterialTypeOut11 】异常信息【{ex.Message}】【{ex.StackTrace}】");
                return null;
            }
        }

        /// <summary>
        /// PLC报错
        /// </summary>
        /// <param name="isFullMaterial"></param>
        /// <param name="materialType"></param>
        /// <returns></returns>
        public static List<WarehouseInfo> MaterialTypeOutPLCError(int isFullMaterial, string materialType, string warehouseCode)
        {
            try
            {
                List<WarehouseInfo> WarehouseInfoList = new List<WarehouseInfo>();

                var warehouseList = _SqlSugarDapper.DB.SqlQueryable<WarehouseInfo>($@"SELECT * FROM WCS_WarehouseInfo WHERE ID IN (  SELECT   ID  FROM   WCS_Warehouse
                        WHERE   IsFullMaterial = {isFullMaterial}  AND MaterialType = '{materialType}' AND WarehouseCode='{warehouseCode}' AND IsOUT = 1 )
                     ORDER BY CreateTime").ToList();

                var warehouseListChangeType = _SqlSugarDapper.DB.SqlQueryable<Warehouse>($@"SELECT   ID  FROM   WCS_Warehouse
                        WHERE   IsFullMaterial = {isFullMaterial} AND WarehouseCode='{warehouseCode}'  AND MaterialType = '{materialType}' AND IsOUT = 1 and NextMaterialType <> ''").ToList();

                if (warehouseListChangeType.Count != 0)
                {
                    foreach (var warehouses in warehouseListChangeType)
                    {
                        GetWarehouseInfo(isFullMaterial, warehouses.ID, ref WarehouseInfoList);
                        if (WarehouseInfoList.Count == 2)
                        {
                            return WarehouseInfoList;
                        }
                    }
                }

                var warehouseListGroup = warehouseList.GroupBy(g => g.ID).ToList();

                foreach (var warehouses in warehouseListGroup)
                {
                    GetWarehouseInfo(isFullMaterial, warehouses.Key, ref WarehouseInfoList);
                    if (WarehouseInfoList.Count == 2)
                    {
                        return WarehouseInfoList;
                    }
                }
                return null;
            }
            catch (Exception ex)
            {
                RunLog.runLog.Error($@"【 MaterialTypeOutPLCError 】异常信息【{ex.Message}】【{ex.StackTrace}】");
                return null;
            }

        }
        /// <summary>
        /// 获取可用库存
        /// </summary>
        /// <param name="isFullMaterial"></param>
        /// <param name="Key"></param>
        /// <param name="WarehouseInfoList"></param>
        public static void GetWarehouseInfo(int isFullMaterial, string Key, ref List<WarehouseInfo> WarehouseInfoList)
        {
            try
            {
                var Warehouse = _SqlSugarDapper.DB.Queryable<Warehouse>().Where(w => w.ID == Key).First();

                var warehouseInfos = _SqlSugarDapper.DB.SqlQueryable<WarehouseInfo>("SELECT *,DATEDIFF(MINUTE, CreateTime,GETDATE()) as dataIff from WCS_WarehouseInfo").Where(w => w.ID == Warehouse.ID).OrderBy(o => o.index).Take(2).ToList();

                if (Warehouse.MaterialType == "PMA后副")
                {
                    if (isFullMaterial == 1)
                    {
                        foreach (var warehouseInfo in warehouseInfos)
                        {
                            if (warehouseInfo.dataIff < 150)
                            {
                                break;
                            }
                            if (warehouseInfo.dataIff > 10080)
                            {
                                break;
                            }
                            if (warehouseInfo.state != (int)StationState.在库)
                            {
                                break;
                            }
                            if (WarehouseInfoList.Count == 0)
                            {
                                //判断PLC第一个有没有货
                                if (Warehouse.Goods1 == 1)
                                {
                                    WarehouseInfoList.Add(warehouseInfo);
                                    continue;
                                }
                                break;
                            }
                            else
                            {
                                //判断PLC第二个有没有货
                                if (Warehouse.Goods2 == 1)
                                {
                                    WarehouseInfoList.Add(warehouseInfo);
                                    return;
                                }
                            }
                        }
                    }
                    else
                    {
                        if (warehouseInfos.Count == 2)
                        {
                            WarehouseInfoList = warehouseInfos;
                            return;
                        }
                    }
                }
                else
                {
                    if (isFullMaterial == 1)
                    {
                        foreach (var warehouseInfo in warehouseInfos)
                        {
                            if (warehouseInfo.dataIff < 120)
                            {
                                //RunLog.runLog.Warning($@"物料未满2小时");
                                break;
                            }
                            if (warehouseInfo.dataIff > 10080)
                            {
                                //RunLog.runLog.Warning($@"物料超过7天");
                                break;
                            }
                            if (warehouseInfo.state != (int)StationState.在库)
                            {
                                //RunLog.runLog.Warning($@"物料被占用");
                                break;
                            }
                            if (WarehouseInfoList.Count == 0)
                            {
                                //判断PLC第一个有没有货
                                if (Warehouse.Goods1 == 1)
                                {
                                    WarehouseInfoList.Add(warehouseInfo);
                                    continue;
                                }
                                break;
                            }
                            else
                            {
                                //判断PLC第二个有没有货
                                if (Warehouse.Goods2 == 1)
                                {
                                    WarehouseInfoList.Add(warehouseInfo);
                                    return;
                                }
                            }
                        }
                    }
                    else
                    {
                        if (warehouseInfos.Count == 2)
                        {
                            WarehouseInfoList = warehouseInfos;
                            return;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                RunLog.runLog.Error($@"【 GetWarehouseInfo 】异常信息【{ex.Message}】【{ex.StackTrace}】");
            }
        }

        /// <summary>
        /// 根据物料类型查找所在仓库
        /// </summary>
        /// <param name="material"></param>
        /// <returns></returns>
        public static List<WarehouseInfo> GetWarehouseByMaterialTypeOut(int isFullMaterial, string materialType)
        {
            List<WarehouseInfo> strings = new List<WarehouseInfo>();

            var warehouseListGroup = _SqlSugarDapper.DB.SqlQueryable<WarehouseInfo>($@"SELECT * FROM WCS_WarehouseInfo WHERE ID IN (  SELECT   ID  FROM   WCS_Warehouse
                        WHERE   IsFullMaterial = {isFullMaterial}  AND MaterialType = '{materialType}' AND IsOUT = 1 )
                     ORDER BY CreateTime").ToList();

            var warehouseListGroup1 = warehouseListGroup.GroupBy(g => g.ID).ToList();

            foreach (var warehouses in warehouseListGroup1)
            {
                var Warehouse = _SqlSugarDapper.DB.Queryable<Warehouse>().Where(w => w.ID == warehouses.Key).First();

                var warehouseInfos = _SqlSugarDapper.DB.SqlQueryable<WarehouseInfo>("SELECT *,DATEDIFF(hh, CreateTime,GETDATE()) as dataIff from WCS_WarehouseInfo").Where(w => w.ID == Warehouse.ID).OrderBy(o => o.index).Take(2).ToList();

                if (isFullMaterial == 1)
                {
                    foreach (var warehouseInfo in warehouseInfos)
                    {
                        if (warehouseInfo.dataIff < 2)
                        {
                            //RunLog.runLog.Warning($@"物料未满2小时");
                            break;
                        }
                        if (warehouseInfo.dataIff > 168)
                        {
                            //RunLog.runLog.Warning($@"物料超过7天");
                            break;
                        }
                        if (warehouseInfo.state != (int)StationState.在库)
                        {
                            //RunLog.runLog.Warning($@"物料被占用");
                            break;
                        }
                        if (strings.Count == 0)
                        {
                            //判断PLC第一个有没有货
                            if (Warehouse.Goods1 == 1)
                            {
                                strings.Add(warehouseInfo);
                                continue;
                            }
                            break;
                        }
                        else
                        {
                            //判断PLC第二个有没有货
                            if (Warehouse.Goods2 == 1)
                            {
                                strings.Add(warehouseInfo);
                                return strings;
                            }
                        }
                    }
                }
                else
                {
                    if (warehouseInfos.Count == 2)
                    {
                        return warehouseInfos;
                    }
                }
            }
            return null;
        }

        /// <summary>
        /// 根据物料类型查找所在仓库
        /// </summary>
        /// <param name="material"></param>
        /// <returns></returns>
        public static Warehouse GetWarehouse(string ID)
        {
            //根据物料号查询这个物料在那个仓库的第几层
            var list = _SqlSugarDapper.DB.Queryable<Warehouse>().Where(w => w.ID == ID).First();
            return list;
        }

        /// <summary>
        /// 根据物料类型查找所在仓库
        /// </summary>
        /// <param name="material"></param>
        /// <returns></returns>
        public static Warehouse GetWarehouseByMaterialTypeIn(int isFullMaterial, string materialType, string warehouseCode)
        {
            try
            {
                var warehouseList = _SqlSugarDapper.DB.SqlQueryable<Warehouse>($@"SELECT w.ID,w.layer,w.WarehouseCode,w.MaterialType, COUNT(i.ID) as count FROM WCS_Warehouse as w 
                        LEFT JOIN WCS_WarehouseInfo  as i ON w.ID = i.ID
                         WHERE w.IsFullMaterial = {isFullMaterial}  AND w.MaterialType = '{materialType}'AND w.WarehouseCode='{warehouseCode}' AND w.IsIN = 1 GROUP BY w.ID,w.layer,w.WarehouseCode,w.MaterialType ORDER BY count").ToList();

                foreach (var item in warehouseList)
                {
                    //判断当前层数有没有任务
                    var task = _SqlSugarDapper.DB.Queryable<WcsTaskConveyor>().Where(w => item.ID.Contains(w.Start_Station) && w.WMSBinCode == item.layer).First();
                    if (task == null && item.count < 20)
                    {
                        return item;
                    }
                }

                //根据物料号查询这个物料在那个仓库的第几层
                var list = _SqlSugarDapper.DB.Queryable<Warehouse>().Where(w => w.MaterialType == materialType && w.IsFullMaterial == isFullMaterial && w.IsIN == 1).OrderBy(o => o.ID).ToList();

                foreach (var item in warehouseList)
                {
                    if (item.count < 18)
                    {
                        return item;
                    }
                }
                return null;
            }
            catch (Exception ex)
            {
                RunLog.runLog.Error($@"【 GetWarehouseByMaterialTypeIn 】异常信息【{ex.Message}】【{ex.StackTrace}】");
                return null;
            }
        }
    }

    public enum MaterialType
    {
        A = 1,
        B = 2,
        C = 3,
        D = 4,
        E = 5,
        F = 6,
        J = 7,
        H = 8,
        I = 9,
        G = 9,
        空 = 11,
    }
}
